package com.lzhl.buildjar.ui;

import com.lzhl.buildjar.App;
import com.lzhl.buildjar.ui.support.*;
import com.lzhl.buildjar.util.FileUtils;
import com.lzhl.buildjar.util.ImageUtils;
import com.lzhl.buildjar.util.StringUtils;
import com.lzhl.buildjar.util.UIUtils;

import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.Map;

/**
 * @author 李柱良(@柱子的日月)
 * @date 2016/5/5
 */
public class ToolUI extends BaseDialog implements ActionListener {
    private static ToolUI toolUI;

    private JButton btnAutoFill;
    private JFileField tfClasspath;
    private JTextField tfPackageName;
    private JTextField tfClassName;

    private JSpinner spLastDays;
    private JSpinner spClassCount;
    private JCheckBox cbIncludeInner;

    private JButton btnClassToJava;
    private JButton btnJavaToClass;

    public ToolUI(Frame owner) {
        super(owner, "工具", true);
        jbinit();
        init();

        setSize(600, 200);
        setLocationRelativeTo(owner);
    }

    private void jbinit() {
        Container container = getContentPane();
        container.setLayout(new BorderLayout());;

        Box boxMain = Box.createVerticalBox();
        boxMain.setBorder(BorderFactory.createEmptyBorder(5, 4, 5, 4));
        container.add(boxMain, BorderLayout.CENTER);

        Dimension pSize = new Dimension(130, 25);
        JLabel label;

        Box boxAutoFill = Box.createHorizontalBox();
        boxAutoFill.setAlignmentX(Component.LEFT_ALIGNMENT);
        boxAutoFill.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
        boxMain.add(boxAutoFill);
        btnAutoFill = new JButton("自动填充最新文件");
        btnAutoFill.setPreferredSize(pSize);
        boxAutoFill.add(btnAutoFill);

        Box boxAutoFillPath = Box.createHorizontalBox();
        boxAutoFillPath.setAlignmentX(Component.LEFT_ALIGNMENT);
        boxAutoFillPath.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
        boxMain.add(boxAutoFillPath);
        boxAutoFillPath.add(Box.createHorizontalStrut(3));
        boxAutoFillPath.add(new JLabel("路径："));
        boxAutoFillPath.add(Box.createHorizontalStrut(2));
        tfClasspath = new JFileField(new FileProvider(true));
        boxAutoFillPath.add(tfClasspath);
        JButton btnClasspath = new JButton(ImageUtils.getImageIcon("browser.png"));
        btnClasspath.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
        boxAutoFillPath.add(btnClasspath);
        JButton btnClassPathPosition = new JButton(ImageUtils.getImageIcon("location.png"));
        btnClassPathPosition.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
        boxAutoFillPath.add(btnClassPathPosition);
        btnClasspath.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JFileChooser chooser = new JFileChooser();
                String classPath = tfClasspath.getText();
                if (classPath != null && classPath.trim().length() > 0) {
                    File dir = new File(classPath);
                    if (dir.isDirectory()) {
                        File parent = dir.getParentFile();
                        if (parent != null) {
                            chooser.setCurrentDirectory(parent);
                        } else {
                            chooser.setCurrentDirectory(dir);
                        }
                    } else {
                        File parent = dir.getParentFile();
                        if (parent != null) {
                            chooser.setCurrentDirectory(parent);
                        }
                    }
                }

                chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                int result = chooser.showOpenDialog(ToolUI.this);
                if (result == JFileChooser.APPROVE_OPTION) {
                    String filePath = chooser.getSelectedFile().getPath();
                    tfClasspath.setText(filePath);
                }
            }
        });
        btnClassPathPosition.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                CheckResult<File> result = checkClassPath();
                if(result.isSucess()) {
                    FileUtils.explorer(result.getData(), false);
                }
            }
        });

        Box boxPackageName = Box.createHorizontalBox();
        boxPackageName.setAlignmentX(Component.LEFT_ALIGNMENT);
        boxPackageName.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
        boxMain.add(boxPackageName);
        boxPackageName.add(Box.createHorizontalStrut(3));
        label = new JLabel("包名：");
        label.setToolTipText("用冒号\":\"分隔可以指定多个包名");
        boxPackageName.add(label);
        boxPackageName.add(Box.createHorizontalStrut(2));
        tfPackageName = new JTextField();
        boxPackageName.add(tfPackageName);

        Box boxClassName = Box.createHorizontalBox();
        boxClassName.setAlignmentX(Component.LEFT_ALIGNMENT);
        boxClassName.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
        boxMain.add(boxClassName);
        boxClassName.add(Box.createHorizontalStrut(3));
        label = new JLabel("类名：");
        label.setToolTipText("用冒号\":\"分隔可以指定多个类名");
        boxClassName.add(label);
        boxClassName.add(Box.createHorizontalStrut(2));
        tfClassName = new JTextField();
        boxClassName.add(tfClassName);

        Box boxAutoFillDays = Box.createHorizontalBox();
        boxAutoFillDays.setAlignmentX(Component.LEFT_ALIGNMENT);
        boxAutoFillDays.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
        boxMain.add(boxAutoFillDays);
        boxAutoFillDays.add(Box.createHorizontalStrut(3));
        boxAutoFillDays.add(new JLabel("天数："));
        boxAutoFillDays.add(Box.createHorizontalStrut(2));
        spLastDays = new JSpinner(new SpinnerNumberModel(1, 0, 365, 1));
        boxAutoFillDays.add(spLastDays);

        boxAutoFillDays.add(Box.createHorizontalStrut(5));
        boxAutoFillDays.add(new JLabel("数量"));
        boxAutoFillDays.add(Box.createHorizontalStrut(2));
        spClassCount = new JSpinner(new SpinnerNumberModel(0, 0, 1000, 1));
        boxAutoFillDays.add(spClassCount);

        cbIncludeInner = new JCheckBox("包含内部类");
        cbIncludeInner.setSelected(true);
        boxAutoFillDays.add(cbIncludeInner);


        boxMain.add(Box.createVerticalStrut(10));
        Box boxTo = Box.createHorizontalBox();
        boxTo.setAlignmentX(Component.LEFT_ALIGNMENT);
        boxTo.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
        boxMain.add(boxTo);
        btnClassToJava = new JButton("class转换为java");
        btnClassToJava.setPreferredSize(pSize);
        boxTo.add(btnClassToJava);
        boxTo.add(Box.createHorizontalStrut(10));
        btnJavaToClass = new JButton("java转换为class");
        btnJavaToClass.setPreferredSize(pSize);
        boxTo.add(btnJavaToClass);
        boxTo.add(Box.createHorizontalGlue());
    }

    private void init() {
        btnAutoFill.putClientProperty("cmd", Cmd.AUTO_FILL);
        btnAutoFill.addActionListener(this);
        btnClassToJava.putClientProperty("cmd", Cmd.TO_JAVA);
        btnClassToJava.addActionListener(this);
        btnJavaToClass.putClientProperty("cmd", Cmd.TO_CLASS);
        btnJavaToClass.addActionListener(this);

        Map<String, String> settings = Setting.getAutoFill();
        tfClasspath.setText(settings.get("autoFill_classpath"));
        tfPackageName.setText(settings.get("autoFill_packageName"));
        tfClassName.setText(settings.get("autoFill_className"));
        String lastDays = settings.get("autoFill_lastDays");
        int iLastDays = 1;
        try {
            iLastDays = Integer.parseInt(lastDays);
        }catch (Exception ignore){}
        if(iLastDays >=0 && iLastDays <= 365) {
            spLastDays.setValue(iLastDays);
        }
        String classCount = settings.get("autoFill_classCount");
        int iClassCount = 0;
        try {
            iClassCount = Integer.parseInt(classCount);
        }catch (Exception ignore){}
        if(iClassCount >=0 && iClassCount <= 1000) {
            spClassCount.setValue(iClassCount);
        }
        String includeInner = settings.get("autoFill_includeInner");
        cbIncludeInner.setSelected("true".equals(includeInner));
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        JButton btn = (JButton) e.getSource();
        final Cmd cmd = (Cmd) btn.getClientProperty("cmd");
        Object temp = null;
        if(cmd.equals(Cmd.AUTO_FILL)) {
            CheckResult<File> result = checkClassPath();
            if(!result.isSucess()) {
                return;
            }
            final AutoFill autoFill = getAutoFill();
            autoFill.setClasspath(result.getData());
            temp = autoFill;
            UIUtils.invoke(new Runnable() {
                @Override
                public void run() {
                    String classpath = "";
                    if (autoFill.getClasspath() != null) {
                        classpath = autoFill.getClasspath().getAbsolutePath();
                    }
                    Setting.setAutoFill(classpath, autoFill.getPackageName(), autoFill.getClassName(),
                            autoFill.getLastDay(), autoFill.getClassCount(), autoFill.isIncludeInner());
                }
            });
        }
        final Object data = temp;
        setVisible(false);
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                App.fireCmd(cmd, data);
            }
        });
    }

    private AutoFill getAutoFill() {
        String packageName = tfPackageName.getText();
        if(packageName == null) {
            packageName = "";
        }
        packageName = packageName.trim();

        String className = tfClassName.getText();
        if(className == null) {
            className = "";
        }
        className = className.trim();

        Integer lastDays = (Integer) spLastDays.getValue();
        Integer classCount = (Integer) spClassCount.getValue();
        boolean includeInner = cbIncludeInner.isSelected();

        return new AutoFill(null, packageName, className, lastDays, classCount, includeInner);
    }

    private CheckResult<File> checkClassPath() {
        CheckResult<File> result = new CheckResult<File>(true);

        String classPath = StringUtils.trim(tfClasspath.getText());
        if(classPath.length() > 0) {
            File classPathDir = new File(classPath);
            if (classPathDir.isDirectory() && !classPath.endsWith(":")) {
                result.setData(classPathDir);
            }
            else {
                JOptionPane.showMessageDialog(this, "类路径设置有误！");
                tfClasspath.requestFocus();
                result.setSucess(false);
            }
        }

        return result;
    }

    @Override
    protected boolean canExit() {
        if(tfClasspath.isSuggesting()) {
            return false;
        }
        return super.canExit();
    }

    public static void show(Frame owner) {
        if(toolUI == null) {
            toolUI = new ToolUI(owner);
        }
        toolUI.btnAutoFill.requestFocus();
        toolUI.setVisible(true);
    }

}
